/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
limitations under the License.*/

package zuo.biao.library.base;

import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.eventhandler.EventHandler;
import ohos.utils.PacMap;
import zuo.biao.library.interfaces.FractionPresenter;
import zuo.biao.library.util.Log;
import zuo.biao.library.util.ResTUtil;

/**通过继承可获取或使用 里面创建的 组件 和 方法
 * @author Lemon
 * @see #context
 * @see #view
 * @see #setContentView
 * @see #runUiThread
 * @see #runThread
 * @use extends BaseFragment, 具体参考
 */
public abstract class BaseFragment extends Fraction implements FractionPresenter {
    private static final String TAG = "BaseFragment";

    /**
     * 添加该Fragment的Activity
     * @warn 不能在子类中创建
     */
    protected BaseAbility context = null;
    /**
     * 该Fragment全局视图
     * @must 非abstract子类的onCreateView中return view;
     * @warn 不能在子类中创建
     */
    protected Component view = null;
    /**
     * 添加这个Fragment视图的布局
     * @warn 不能在子类中创建
     */
    protected ComponentContainer container = null;

    private boolean isAlive = false;
    private boolean isRunning = false;

    /**
     * 在非abstract子类的onCreateView中super.onCreateView且return view;
     * @param intent intent
     */
    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
    }

    /**设置界面布局
     * @warn 最多调用一次
     * @param layoutResID layoutResID
     * @use 在onCreateView后调用
     */
    public void setContentView(int layoutResID) {
        LayoutScatter.getInstance(getContext()).parse(layoutResID, null, false);
    }

    /**
     * 可用于 打开activity与fragment，fragment与fragment之间的通讯（传值）等
     */
    protected PacMap argument = null;
    /**
     * 可用于 打开activity以及activity之间的通讯（传值）等；一些通讯相关基本操作（打电话、发短信等）
     */
    protected Intent intent = null;

    /**通过id查找并获取控件，使用时不需要强转
     * openharmonyos 不支持
     * @param id id
     * @return findView
     */
    @Deprecated
    public <V extends Component> V findView(int id) {
        return (V) view.findComponentById(id);
    }
    /**通过id查找并获取控件，并setOnClickListener
     * @param id id
     * @param l l
     * @return Component
     */
    @Deprecated
    public <V extends Component> V findView(int id, Component.ClickedListener l) {
//        V v = (V) findComponentById(id);
//        v.setClickedListener(l);
        return null;
    }
    /**通过id查找并获取控件，使用时不需要强转
     *  openharmonyos 不支持
     * @warn 调用前必须调用setContentView
     * @param id id
     * @return findViewById
     */
    @Deprecated
    public <V extends Component> V findViewById(int id) {
        return findView(id);
    }
    /**通过id查找并获取控件，并setOnClickListener
     * @param id id
     * @param l l
     * @return findViewById
     */
    @Deprecated
    public <V extends Component> V findViewById(int id, Component.ClickedListener l) {
        return findView(id, l);
    }

    public Intent getIntent() {
        return context.getIntent();
    }

    // 运行线程<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    /**在UI线程中运行，建议用这个方法代替runOnUiThread
     * @param action action
     */
    public final void runUiThread(Runnable action) {
        if (isAlive() == false) {
            Log.warn(TAG, "runUiThread  isAlive() == false >> return;");
            return;
        }
        context.runUiThread(action);
    }
    /**运行线程
     * @param name name
     * @param runnable runnable
     * @return 线程
     */
    public final EventHandler runThread(String name, Runnable runnable) {
        if (isAlive() == false) {
            Log.warn(TAG, "runThread  isAlive() == false >> return null;");
            return null;
        }
        return context.runThread(name + hashCode(), runnable); // name, runnable);同一Activity出现多个同名Fragment可能会出错
    }

    // 运行线程>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    // 进度弹窗<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    /**展示加载进度条,无标题
     * @param stringResId stringResId
     */
    public void showProgressDialog(int stringResId) {
        if (isAlive() == false) {
            Log.warn(TAG, "showProgressDialog  isAlive() == false >> return;");
            return;
        }
        context.showProgressDialog(ResTUtil.getString(context, stringResId));
    }

    /**展示加载进度条
     * @param dialogMessage 信息
     */
    public void showProgressDialog(String dialogMessage) {
        if (isAlive() == false) {
            Log.warn(TAG, "showProgressDialog  isAlive() == false >> return;");
            return;
        }
        context.showProgressDialog(dialogMessage);
    }

    /** 隐藏加载进度
     */
    public void dismissProgressDialog() {
        if (isAlive() == false) {
            Log.warn(TAG, "dismissProgressDialog  isAlive() == false >> return;");
            return;
        }
        context.dismissProgressDialog();
    }
    // 进度弹窗>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    // 启动Activity<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    /**打开新的Activity，向左滑入效果
     * @param intent
     */
    public void toAbility(Intent intent) {
        toAbility(intent, true);
    }
    /**打开新的Activity
     * @param intent intent
     * @param showAnimation showAnimation
     */
    public void toAbility(Intent intent, boolean showAnimation) {
        toAbility(intent, -1, showAnimation);
    }
    /**打开新的Activity，向左滑入效果
     * @param intent intent
     * @param requestCode requestCode
     */
    public void toAbility(Intent intent, int requestCode) {
        toAbility(intent, requestCode, true);
    }
    /**打开新的Activity
     * @param intent intent
     * @param requestCode requestCode
     * @param showAnimation showAnimation
     */
    public void toAbility(final Intent intent, final int requestCode, final boolean showAnimation) {
        runUiThread(
                new Runnable() {
                    @Override
                    public void run() {
                        if (intent == null) {
                            Log.warn(TAG, "toActivity  intent == null >> return;");
                            return;
                        }
                        // fragment中使用context.startActivity会导致在fragment中不能正常接收onActivityResult
                        if (requestCode < 0) {
                            startAbility(intent,requestCode);
                        } else {
                            startAbility(intent, requestCode);
                        }
                    }
                });
    }
    // 启动Activity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    // show short toast<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    /**快捷显示short toast方法，需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
     * @param stringResId stringResId
     */
    public void showShortToast(int stringResId) {
        if (isAlive() == false) {
            Log.warn(TAG, "showProgressDialog  isAlive() == false >> return;");
            return;
        }
        context.showShortToast(stringResId);
    }
    /**快捷显示short toast方法，需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
     * @param string string
     */
    public void showShortToast(String string) {
        if (isAlive() == false) {
            Log.warn(TAG, "showProgressDialog  isAlive() == false >> return;");
            return;
        }
        context.showShortToast(string);
    }
    /**快捷显示short toast方法，需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
     * @param string string
     * @param isForceDismissProgressDialog isForceDismissProgressDialog
     */
    public void showShortToast(String string, boolean isForceDismissProgressDialog) {
        if (isAlive() == false) {
            Log.warn(TAG, "showProgressDialog  isAlive() == false >> return;");
            return;
        }
        context.showShortToast(string, isForceDismissProgressDialog);
    }
    // show short toast>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    @Override
    public final boolean isAlive() {
        return isAlive && context != null; // & ! isRemoving();导致finish，onDestroy内runUiThread不可用
    }

    @Override
    public final boolean isRunning() {
        return isRunning & isAlive();
    }

    @Override
    protected void onForeground(Intent intent) {
        super.onForeground(intent);
        isRunning = true;
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        isRunning = false;
    }

    /**销毁并回收内存
     * @warn 子类如果要使用这个方法内用到的变量，应重写onDestroy方法并在super.onDestroy();前操作
     */
    @Override
    protected void onStop() {
        super.onStop();
        dismissProgressDialog();
        isAlive = false;
        isRunning = false;
        view = null;
        container = null;

        intent = null;
        argument = null;

        context = null;

        Log.debug(TAG, "onDestroy >>>>>>>>>>>>>>>>>>>>>>>>\n");
    }
}
